﻿using MathNet.Numerics.LinearAlgebra;
using MathNet.Numerics.RootFinding;
using MatlabWork.Entity;
using MatlabWork.Model;
using OfficeOpenXml.DataValidation;
using OfficeOpenXml.FormulaParsing.Excel.Functions;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using OfficeOpenXml.FormulaParsing.Excel.Functions.RefAndLookup;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Shell;
using System.Xml.Linq;

namespace MatlabWork.Dal
{
    public class Calculate
    {
        // 定义地球的常量
        private const double EarthSemiMajorAxis = 6378137.0; // 地球的半长轴，单位：米
        private const double EarthFlattening = 1 / 298.257223563; // 地球的扁率
        private const double EarthSemiMinorAxis = EarthSemiMajorAxis * (1 - EarthFlattening); // 地球的半短轴，单位：米

        public double w = -7.292115 * Math.Pow(10,-5);
        public double C = 2.99792458458 * Math.Pow(10, 8);
        public double fu = 0.0;
        public double ff = 0.0;
        //终端
        public double x_st = 0.0;// 6371 * Math.Cos(123.504394710077) * Math.Cos(31.788813244661) * Math.Pow(10,3);
        public double y_st = 0.0;// 6371 * Math.Cos(123.504394710077) * Math.Sin(31.788813244661) * Math.Pow(10,3);
        public double z_st = 0.0;
        //基站
        public double x_bs = 0.0;// 6371 * Math.Cos(122.885488594512) * Math.Cos(32.205547319648) * Math.Pow(10,3);
        public double y_bs = 0.0;// 6371 * Math.Cos(122.885488594512) * Math.Sin(32.205547319648) * Math.Pow(10,3);
        public double z_bs = 0.0;

        public CalculateValue calculateValue { get; set; }
        // 轨道半长轴
        public double _delta_a = 4.249 * Math.Pow(10, -3);
        //轨道偏心率
        public double _e = 1.431 * Math.Pow(10, -8);
        //轨道倾角
        public double _delta_i = Math.Pow(2, -27);
        //参考时刻升交
        public double _OMEGA0 = Math.Pow(2, -27);
        //近地点幅
        public double _omega = Math.Pow(2, -27);
        //平近点角
        public double _M0 = Math.Pow(2, -27);
        public int Aref = 6500000;
        //新版协议偏移量
        public int i0ref = 0;
        public double miu = 3.986004418 * Math.Pow(10, 14);
        public double OMEGAe = 7.2921150 * Math.Pow(10, -5);

        public List<TD> TDus = new List<TD>();
        //Sat2BS
        public List<TD> TDfs = new List<TD>();
        //Total
        public List<TD> TDtotals = new List<TD>();

        public List<TD> deltafus = new List<TD>();
        //Sat2BS
        public List<TD> deltaffs = new List<TD>();
        //Total
        public List<TD> deltatotals = new List<TD>();

        public List<numTest> numlist = new List<numTest>();

        public Calculate()
        {
        }

        public Calculate(CalculateValue calculateValue)
        {
            this.fu = calculateValue.fu * Math.Pow(10, 9); 
            this.ff = calculateValue.ff * Math.Pow(10, 9); 
            this.x_st = calculateValue.x_st;
            this.y_st = calculateValue.y_st;
            this.z_st = calculateValue.z_st;
            this.x_bs = calculateValue.x_bs;
            this.y_bs = calculateValue.y_bs;
            this.z_bs = calculateValue.z_bs;
            this.calculateValue = calculateValue;
        }

        public void CalculateLocation(List<SateliteData> sateliteDatas, string sateName, int StartTime, int LastTime, string folderName)
        {
            TDus.Clear();
            TDfs.Clear();
            TDtotals.Clear();
            deltaffs.Clear();
            deltafus.Clear();
            deltatotals.Clear();
            numlist.Clear();
            ControlExcel controlExcel = new ControlExcel();
            DateTime time = new DateTime(2020, 1, 1);
            foreach (var item in sateliteDatas)
            {

                double can_sec = item.utcSecond;
                double delta_a = item.delta_a * _delta_a;
                double e = item.e * _e;
                double delta_i = item.delta_i * _delta_i;
                double OMEGA0 = item.OMEGA0 * _OMEGA0;
                double omega = item.omega * _omega;
                double M0 = item.M0 * _M0;

                //double tk = t - t0e;
                int tk = 0;
                while (tk < 60)
                {
                    double canSec = can_sec + tk;
                    double d = (canSec / 604800);
                    double WN = Math.Floor(d); //周计数                    
                    int daysToAdd = (int)WN * 7;
                    DateTime newDate = time.AddDays(daysToAdd);
                    double SOW = Math.IEEERemainder(canSec, 604800); //周内秒
                    double SOW2 = canSec % 604800;
                    //DateTime addSecondDate = newDate.AddSeconds(SOW);
                    DateTime addSecondDate = time.AddSeconds(canSec);
                    numTest numTest = new numTest();
                    double a = Aref + delta_a;
                    double i0 = (i0ref + delta_i) * Math.PI;
                    double n0 = Math.Sqrt(miu / Math.Pow(a, 3));
                    double MK = (M0 * Math.PI) + (n0 * tk);

                    Func<double, double> function = Ek => Ek - (e * Math.Sin(Ek)) - MK;
                    double EK = Bisection.FindRoot(function, -10000000, 10000000, 1E-12);

                    double vk = Math.Atan2((Math.Sqrt(1 - Math.Pow(e, 2)) * Math.Sin(EK)), (Math.Cos(EK) - e));
                    double uk = vk + omega * Math.PI;
                    double rk = a * (1 - e * Math.Cos(EK));
                    double OMEGAk = (OMEGA0 * Math.PI) - (OMEGAe * tk);
                    double xp = rk * Math.Cos(uk);
                    double yp = rk * Math.Sin(uk);
                    double xs = xp * Math.Cos(OMEGAk) - (yp * Math.Cos(i0) * Math.Sin(OMEGAk));
                    double ys = xp * Math.Sin(OMEGAk) + (yp * Math.Cos(i0) * Math.Cos(OMEGAk));
                    double zs = yp * Math.Sin(i0);
                    double dEk = n0 / (1 - e * Math.Cos(EK));
                    double duk = Math.Sqrt(1 - e * e) * dEk / (1 - e * Math.Cos(EK));
                    double drk = a * e * Math.Sin(EK) * dEk;
                    double dOMEGAK = -OMEGAe;
                    double dxk = (drk * Math.Cos(uk)) - (rk * duk * Math.Sin(uk));
                    double dyk = (drk * Math.Sin(uk)) + (rk * duk * Math.Cos(uk));
                    Matrix<double> dr = Matrix<double>.Build.DenseOfArray(new double[,]
                {
            {Math.Cos(OMEGAk), -(Math.Sin(OMEGAk) * Math.Cos(i0)), -((xp * Math.Sin(OMEGAk)) + (yp * Math.Cos(OMEGAk) * Math.Cos(i0)))},
            {Math.Sin(OMEGAk), (Math.Cos(OMEGAk) * Math.Cos(i0)), ((xp * Math.Cos(OMEGAk)) - (yp * Math.Sin(OMEGAk) * Math.Cos(i0)))},
            {0, Math.Sin(i0), 0}
                });
                    Vector<double> vector1x3 = Vector<double>.Build.DenseOfArray(new double[] { dxk, dyk, dOMEGAK });
                    Vector<double> result = dr * vector1x3;
                    numTest.can_sec = canSec;
                    numTest.x = xs;
                    numTest.y = ys;
                    numTest.z = zs;
                    numTest.vx = result[0];
                    numTest.vy = result[1];
                    numTest.vz = result[2];
                    numTest.EK = EK;
                    numlist.Add(numTest);
                    calcumn(numTest.can_sec, addSecondDate, numTest.x, numTest.y, numTest.z, numTest.vx, numTest.vy, numTest.vz);
                    tk++;
                }

            }
            DateTime StartDate = time.AddSeconds(StartTime);
            int index = StartTime;
            int endIndex = LastTime;
            ControlTxT controlTxT = new ControlTxT();
            string uName = "u_" + sateName + "_single_" + "gm";
            string fName = "f_" + sateName + "_single_" + "gm";
            string uName1 = "u_" + sateName + "_single_" + LastTime.ToString() + "gm";
            string fName1 = "f_" + sateName + "_single_" + LastTime.ToString() + "gm";
            string totalName = "total_" + sateName + "_single_" + "gm";
            string totalName1 = "total_" + sateName + LastTime.ToString() + "_single_" + "gm";

            if (controlExcel.insertExcel127(folderName, uName))
                controlExcel.insertExcel(folderName, uName, TDus, deltafus);
            if (controlExcel.insertExcel472(folderName, fName))
                controlExcel.insertExcel(folderName, fName, TDfs, deltaffs);
            if (controlExcel.insertExcel(folderName, totalName))
                controlExcel.insertExcel(folderName, totalName, TDtotals, deltatotals);

            if (index != 0 && endIndex != 0)
            {
                if (controlExcel.insertExcel127(folderName, uName1))
                    controlExcel.insertExcel(folderName, uName1, TDus, deltafus, index, endIndex);
                if (controlExcel.insertExcel472(folderName, fName1))
                    controlExcel.insertExcel(folderName, fName1, TDfs, deltaffs, index, endIndex);
                if (controlExcel.insertExcel472(folderName, totalName1))
                    controlExcel.insertExcel(folderName, totalName1, TDtotals, deltatotals, index, endIndex);

                controlTxT.insertASO127(folderName, uName1, TDus, deltafus, index, endIndex);
                controlTxT.insertASO472(folderName, fName1, TDfs, deltaffs, index, endIndex);
                controlTxT.insertASO(folderName, totalName1, TDtotals, deltatotals, index, endIndex);

            }
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_single_gm";
            location location = new location();
            controlExcel.insertExcel(folderName, fileName, TDus, TDfs, numlist, location);

        }

        public void CalculateLocation(List<SateliteData> sateliteDatas, string sateName, int StartTime, int LastTime, int preferTime, int centerTime, int centerNumber, bool flag, string folderName)
        {
            TDus.Clear();
            TDfs.Clear();
            TDtotals.Clear();
            deltaffs.Clear();
            deltafus.Clear();
            deltatotals.Clear();
            numlist.Clear();
            ControlExcel controlExcel = new ControlExcel();
            DateTime time = new DateTime(2020, 1, 1);
            foreach (var item in sateliteDatas)
            {

                double can_sec = item.utcSecond;
                double delta_a = item.delta_a * _delta_a;
                double e = item.e * _e;
                double delta_i = item.delta_i * _delta_i;
                double OMEGA0 = item.OMEGA0 * _OMEGA0;
                double omega = item.omega * _omega;
                double M0 = item.M0 * _M0;

                //double tk = t - t0e;
                int tk = 0;
                while (tk < 60)
                {
                    double canSec = can_sec + tk;
                    double d = (canSec / 604800);
                    double WN = Math.Floor(d); //周计数                    
                    int daysToAdd = (int)WN * 7;
                    DateTime newDate = time.AddDays(daysToAdd);
                    double SOW = Math.IEEERemainder(canSec, 604800); //周内秒
                    //DateTime addSecondDate = newDate.AddSeconds(canSec);
                    DateTime addSecondDate = time.AddSeconds(canSec);

                    numTest numTest = new numTest();
                    double a = Aref + delta_a;
                    double i0 = (i0ref + delta_i) * Math.PI;
                    double n0 = Math.Sqrt(miu / Math.Pow(a, 3));
                    double MK = (M0 * Math.PI) + (n0 * tk);

                    Func<double, double> function = Ek => Ek - (e * Math.Sin(Ek)) - MK;
                    double EK = Bisection.FindRoot(function, -10000000, 10000000, 1E-12);

                    double vk = Math.Atan2((Math.Sqrt(1 - Math.Pow(e, 2)) * Math.Sin(EK)), (Math.Cos(EK) - e));
                    double uk = vk + omega * Math.PI;
                    double rk = a * (1 - e * Math.Cos(EK));
                    double OMEGAk = (OMEGA0 * Math.PI) - (OMEGAe * tk);
                    double xp = rk * Math.Cos(uk);
                    double yp = rk * Math.Sin(uk);
                    double xs = xp * Math.Cos(OMEGAk) - (yp * Math.Cos(i0) * Math.Sin(OMEGAk));
                    double ys = xp * Math.Sin(OMEGAk) + (yp * Math.Cos(i0) * Math.Cos(OMEGAk));
                    double zs = yp * Math.Sin(i0);
                    double dEk = n0 / (1 - e * Math.Cos(EK));
                    double duk = Math.Sqrt(1 - e * e) * dEk / (1 - e * Math.Cos(EK));
                    double drk = a * e * Math.Sin(EK) * dEk;
                    double dOMEGAK = -OMEGAe;
                    double dxk = (drk * Math.Cos(uk)) - (rk * duk * Math.Sin(uk));
                    double dyk = (drk * Math.Sin(uk)) + (rk * duk * Math.Cos(uk));
                    Matrix<double> dr = Matrix<double>.Build.DenseOfArray(new double[,]
                {
            {Math.Cos(OMEGAk), -(Math.Sin(OMEGAk) * Math.Cos(i0)), -((xp * Math.Sin(OMEGAk)) + (yp * Math.Cos(OMEGAk) * Math.Cos(i0)))},
            {Math.Sin(OMEGAk), (Math.Cos(OMEGAk) * Math.Cos(i0)), ((xp * Math.Cos(OMEGAk)) - (yp * Math.Sin(OMEGAk) * Math.Cos(i0)))},
            {0, Math.Sin(i0), 0}
                });
                    Vector<double> vector1x3 = Vector<double>.Build.DenseOfArray(new double[] { dxk, dyk, dOMEGAK });
                    Vector<double> result = dr * vector1x3;
                    numTest.can_sec = canSec;
                    numTest.x = xs;
                    numTest.y = ys;
                    numTest.z = zs;
                    numTest.vx = result[0];
                    numTest.vy = result[1];
                    numTest.vz = result[2];
                    numTest.EK = EK;
                    numlist.Add(numTest);
                    calcumn(numTest.can_sec, addSecondDate, numTest.x, numTest.y, numTest.z, numTest.vx, numTest.vy, numTest.vz);
                    tk++;
                }

            }
            DateTime StartDate = time.AddSeconds(StartTime);
            int index = TDus.Select((TD, i) => new { TD = TD, Index = i })
                             .Where(p => p.TD.Time == StartDate)
                             .Select(p => p.Index)
                             .FirstOrDefault();
            int endIndex = index + LastTime - 1;
            int preferIndex = index - preferTime;
            ControlTxT controlTxT = new ControlTxT();
            string uName = "u_" + sateName + "_double_" + "gm";
            string fName = "f_" + sateName + "_double_" + "gm";
            string uName1 = "u_" + sateName + "_double_" + LastTime.ToString() + "gm";
            string fName1 = "f_" + sateName + "_double_" + LastTime.ToString() + "gm";
            string totalName = "total_" + sateName + "_double_" + "gm";
            string totalName1 = "total_" + sateName + "_double_" + LastTime.ToString() + "_" + "gm";

            if (controlExcel.insertExcel127(folderName, uName))
                controlExcel.insertExcel(folderName, uName, TDus, deltafus);
            if (controlExcel.insertExcel472(folderName, fName))
                controlExcel.insertExcel(folderName, fName, TDfs, deltaffs);
            if (controlExcel.insertExcel(folderName, totalName))
                controlExcel.insertExcel(folderName, totalName, TDtotals, deltatotals);

            if (index != 0 && endIndex != 0)
            {
                if (controlExcel.insertExcel127(folderName, uName1))
                    controlExcel.insertExcel(folderName, uName1, TDus, deltafus, index, endIndex);
                if (controlExcel.insertExcel472(folderName, fName1))
                    controlExcel.insertExcel(folderName, fName1, TDfs, deltaffs, index, endIndex);
                if (controlExcel.insertExcel472(folderName, totalName1))
                    controlExcel.insertExcel(folderName, totalName1, TDtotals, deltatotals, index, endIndex);

                controlTxT.insertASO127(folderName, uName1, TDus, deltafus, index, endIndex);
                controlTxT.insertASO472(folderName, fName1, TDfs, deltaffs, index, endIndex);
                //controlTxT.insertASO(folderName, totalName1, TDtotals, deltatotals, index, endIndex);
                if (flag)
                {
                    controlTxT.insertASOPre(folderName, totalName1, TDfs, deltaffs, index, endIndex, centerTime, centerNumber);
                    controlTxT.insertASOPre(folderName, totalName1, TDtotals, deltatotals, index, endIndex, centerTime, centerNumber);
                }
                else
                {
                    controlTxT.insertASOAft(folderName, totalName1, TDfs, deltaffs, index, endIndex, centerTime, centerNumber);
                    controlTxT.insertASOAft(folderName, totalName1, TDtotals, deltatotals, index, endIndex, centerTime, centerNumber);
                }
            }
            controlTxT.insertUni(folderName, sateName, numlist);
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "gm";
            location location = new location();
            controlExcel.insertExcel(folderName, fileName, TDus, TDfs, numlist, location);
        }

        public List<numTest> CalculateLocation(List<SateliteData> sateliteDatas)
        {
            List<numTest> numlist = new List<numTest>();
            DateTime time = new DateTime(2020, 1, 1);
            foreach (var item in sateliteDatas)
            {

                double can_sec = item.utcSecond;
                double delta_a = item.delta_a * _delta_a;
                double e = item.e * _e;
                double delta_i = item.delta_i * _delta_i;
                double OMEGA0 = item.OMEGA0 * _OMEGA0;
                double omega = item.omega * _omega;
                double M0 = item.M0 * _M0;

                //double tk = t - t0e;
                int tk = 0;
                while (tk < 60)
                {
                    double canSec = can_sec + tk;
                    DateTime addSecondDate = time.AddSeconds(canSec);
                    numTest numTest = new numTest();
                    double a = Aref + delta_a;
                    double i0 = (i0ref + delta_i) * Math.PI;
                    double n0 = Math.Sqrt(miu / Math.Pow(a, 3));
                    double MK = (M0 * Math.PI) + (n0 * tk);

                    Func<double, double> function = Ek => Ek - (e * Math.Sin(Ek)) - MK;
                    double EK = Bisection.FindRoot(function, -10000000, 10000000, 1E-12);

                    double vk = Math.Atan2((Math.Sqrt(1 - Math.Pow(e, 2)) * Math.Sin(EK)), (Math.Cos(EK) - e));
                    double uk = vk + omega * Math.PI;
                    double rk = a * (1 - e * Math.Cos(EK));
                    double OMEGAk = (OMEGA0 * Math.PI) - (OMEGAe * tk);
                    double xp = rk * Math.Cos(uk);
                    double yp = rk * Math.Sin(uk);
                    double xs = xp * Math.Cos(OMEGAk) - (yp * Math.Cos(i0) * Math.Sin(OMEGAk));
                    double ys = xp * Math.Sin(OMEGAk) + (yp * Math.Cos(i0) * Math.Cos(OMEGAk));
                    double zs = yp * Math.Sin(i0);
                    double dEk = n0 / (1 - e * Math.Cos(EK));
                    double duk = Math.Sqrt(1 - e * e) * dEk / (1 - e * Math.Cos(EK));
                    double drk = a * e * Math.Sin(EK) * dEk;
                    double dOMEGAK = -OMEGAe;
                    double dxk = (drk * Math.Cos(uk)) - (rk * duk * Math.Sin(uk));
                    double dyk = (drk * Math.Sin(uk)) + (rk * duk * Math.Cos(uk));
                    Matrix<double> dr = Matrix<double>.Build.DenseOfArray(new double[,]
                {
            {Math.Cos(OMEGAk), -(Math.Sin(OMEGAk) * Math.Cos(i0)), -((xp * Math.Sin(OMEGAk)) + (yp * Math.Cos(OMEGAk) * Math.Cos(i0)))},
            {Math.Sin(OMEGAk), (Math.Cos(OMEGAk) * Math.Cos(i0)), ((xp * Math.Cos(OMEGAk)) - (yp * Math.Sin(OMEGAk) * Math.Cos(i0)))},
            {0, Math.Sin(i0), 0}
                });
                    Vector<double> vector1x3 = Vector<double>.Build.DenseOfArray(new double[] { dxk, dyk, dOMEGAK });
                    Vector<double> result = dr * vector1x3;
                    numTest.can_sec = canSec;
                    numTest.x = xs;
                    numTest.y = ys;
                    numTest.z = zs;
                    numTest.vx = result[0];
                    numTest.vy = result[1];
                    numTest.vz = result[2];
                    numTest.EK = EK;
                    numTest.Time = addSecondDate;
                    numlist.Add(numTest);
                    tk++;
                }
            }
            return numlist;
        }

        public List<numTest> CalculateLocation(List<SateliteData> sateliteDatas, double addsecond)
        {
            List<numTest> numlist = new List<numTest>();
            DateTime time = new DateTime(2020, 1, 1);
            foreach (var item in sateliteDatas)
            {

                double can_sec = item.utcSecond;
                double delta_a = item.delta_a * _delta_a;
                double e = item.e * _e;
                double delta_i = item.delta_i * _delta_i;
                double OMEGA0 = item.OMEGA0 * _OMEGA0;
                double omega = item.omega * _omega;
                double M0 = item.M0 * _M0;

                //double tk = t - t0e;
                double tk = 0;
                while (tk < 60)
                {
                    double canSec = can_sec + tk;
                    DateTime addSecondDate = time.AddSeconds(canSec);
                    numTest numTest = new numTest();
                    double a = Aref + delta_a;
                    double i0 = (i0ref + delta_i) * Math.PI;
                    double n0 = Math.Sqrt(miu / Math.Pow(a, 3));
                    double MK = (M0 * Math.PI) + (n0 * tk);

                    Func<double, double> function = Ek => Ek - (e * Math.Sin(Ek)) - MK;
                    double EK = Bisection.FindRoot(function, -10000000, 10000000, 1E-12);

                    double vk = Math.Atan2((Math.Sqrt(1 - Math.Pow(e, 2)) * Math.Sin(EK)), (Math.Cos(EK) - e));
                    double uk = vk + omega * Math.PI;
                    double rk = a * (1 - e * Math.Cos(EK));
                    double OMEGAk = (OMEGA0 * Math.PI) - (OMEGAe * tk);
                    double xp = rk * Math.Cos(uk);
                    double yp = rk * Math.Sin(uk);
                    double xs = xp * Math.Cos(OMEGAk) - (yp * Math.Cos(i0) * Math.Sin(OMEGAk));
                    double ys = xp * Math.Sin(OMEGAk) + (yp * Math.Cos(i0) * Math.Cos(OMEGAk));
                    double zs = yp * Math.Sin(i0);
                    double dEk = n0 / (1 - e * Math.Cos(EK));
                    double duk = Math.Sqrt(1 - e * e) * dEk / (1 - e * Math.Cos(EK));
                    double drk = a * e * Math.Sin(EK) * dEk;
                    double dOMEGAK = -OMEGAe;
                    double dxk = (drk * Math.Cos(uk)) - (rk * duk * Math.Sin(uk));
                    double dyk = (drk * Math.Sin(uk)) + (rk * duk * Math.Cos(uk));
                    Matrix<double> dr = Matrix<double>.Build.DenseOfArray(new double[,]
                {
            {Math.Cos(OMEGAk), -(Math.Sin(OMEGAk) * Math.Cos(i0)), -((xp * Math.Sin(OMEGAk)) + (yp * Math.Cos(OMEGAk) * Math.Cos(i0)))},
            {Math.Sin(OMEGAk), (Math.Cos(OMEGAk) * Math.Cos(i0)), ((xp * Math.Cos(OMEGAk)) - (yp * Math.Sin(OMEGAk) * Math.Cos(i0)))},
            {0, Math.Sin(i0), 0}
                });
                    Vector<double> vector1x3 = Vector<double>.Build.DenseOfArray(new double[] { dxk, dyk, dOMEGAK });
                    Vector<double> result = dr * vector1x3;
                    numTest.can_sec = canSec;
                    numTest.x = xs;
                    numTest.y = ys;
                    numTest.z = zs;
                    numTest.vx = result[0];
                    numTest.vy = result[1];
                    numTest.vz = result[2];
                    numTest.EK = EK;
                    numTest.Time = addSecondDate;
                    numlist.Add(numTest);
                    tk  = tk + addsecond;
                }
            }
            return numlist;
        }


        public void calcumn(double can_sec, DateTime dateTime, double x, double y, double z, double vx, double vy, double vz)
        {
            TD tDu = new TD();
            tDu.Time = dateTime;
            TD tDf = new TD();
            tDf.Time = dateTime;
            TD TDtotal = new TD();
            TDtotal.Time = dateTime;
            TD deltaFu = new TD();
            deltaFu.Time = dateTime;
            TD deltaFf = new TD();
            deltaFf.Time = dateTime;
            TD deltatotal = new TD();
            deltatotal.Time = dateTime;

            double WN = Math.Floor(can_sec / 604800); //周计数
            double SOW = Math.IEEERemainder(can_sec, 604800); //周内秒

            double x_sat = x;
            double y_sat = y;
            double z_sat = z;

            double vx_sat = vx;
            double vy_sat = vy;
            double vz_sat = vz;
            double latitude = 0;
            double longitude = 0;
            //终端
            //double x_st = -2756713.92312829;// 6371 * Math.Cos(123.504394710077) * Math.Cos(31.788813244661) * Math.Pow(10,3);
            //double y_st = 4846389.73817725;// 6371 * Math.Cos(123.504394710077) * Math.Sin(31.788813244661) * Math.Pow(10,3);
            //double z_st = 3086979.55837501;
            ////基站
            //double x_bs = -2940375.29831781;// 6371 * Math.Cos(122.885488594512) * Math.Cos(32.205547319648) * Math.Pow(10,3);
            //double y_bs = 4577649.51662709;// 6371 * Math.Cos(122.885488594512) * Math.Sin(32.205547319648) * Math.Pow(10,3);
            //double z_bs = 3317495.47186574;

            double[] ep = { (x_sat - x_st), (y_sat - y_st), (z_sat - z_st) };
            double normep = CalculateEuclideanNorm(ep);
            double[] ep1 = { (x_sat - x_bs), (y_sat - y_bs), (z_sat - z_bs) };
            double normep1 = CalculateEuclideanNorm(ep1);
            for (int j = 0; j < ep.Length; j++) { ep[j] = ep[j] / normep; }
            for (int j = 0; j < ep1.Length; j++) { ep1[j] = ep1[j] / normep1; }

            //多普勒频偏计算
            double vdu = (vx_sat * ep[0]) + (vy_sat * ep[1]) + (vz_sat * ep[2]);
            double deltafu = vdu / C * fu * (-1);
            double vdf = (vx_sat * ep1[0]) + (vy_sat * ep1[1]) + (vz_sat * ep1[2]);
            double deltaff = vdf / C * ff * (-1);

            //延时计算
            double Lu = Math.Sqrt((x_sat - x_st) * (x_sat - x_st) + (y_sat - y_st) * (y_sat - y_st) + (z_sat - z_st) * (z_sat - z_st));
            double TDu = Lu / C;
            double Lf = Math.Sqrt((x_sat - x_bs) * (x_sat - x_bs) + (y_sat - y_bs) * (y_sat - y_bs) + (z_sat - z_bs) * (z_sat - z_bs));
            double TDf = Lf / C;

            tDu.number = TDu;
            tDf.number = TDf;
            TDtotal.number = TDf + TDu;
            deltaFu.number = deltafu;
            deltaFf.number = deltaff;
            deltatotal.number = deltafu + deltaff;
            TDus.Add(tDu);
            TDfs.Add(tDf);
            TDtotals.Add(TDtotal);
            deltafus.Add(deltaFu);
            deltaffs.Add(deltaFf);
            deltatotals.Add(deltatotal);

        }

        public void InsertExcel(string sateName, int StartTime, int LastTime, int index, int endIndex)
        {
            ControlExcel controlExcel = new ControlExcel();
            string folderName = controlExcel.CreateFold(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));

            controlExcel.insertExcel(folderName, DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"), numlist);
            string TDuName = "TDu_" + sateName + "_" + "gm";
            string TDfName = "TDf_" + sateName + "_" + "gm";
            string TDName = "TD_" + sateName + "_" + "gm";
            string deltaduName = "deltadu_" + sateName + "_" + "gm";
            string deltadfName = "deltadf_" + sateName + "_" + "gm";
            string deltaName = "delta_" + sateName + "_" + "gm";

            string TDuName1 = "TDu_" + sateName + "_" + LastTime.ToString() + "gm";
            string TDfName1 = "TDf_" + sateName + "_" + LastTime.ToString() + "gm";
            string TDName1 = "TD_" + sateName + "_" + LastTime.ToString() + "gm";
            string deltaduName1 = "deltadu_" + sateName + "_" + LastTime.ToString() + "gm";
            string deltadfName1 = "deltadf_" + sateName + "_" + LastTime.ToString() + "gm";
            string deltaName1 = "delta_" + sateName + "_" + LastTime.ToString() + "gm";
            string Excelname = DateTime.Now.ToString("yyyyMMddHHmmss") + "gm";

            if (controlExcel.insertExcel127(folderName, TDuName))
                controlExcel.insertExcel(folderName, TDuName, TDus);
            if (controlExcel.insertExcel472(folderName, TDfName))
                controlExcel.insertExcel(folderName, TDfName, TDfs);
            if (controlExcel.insertExcel127(folderName, TDName))
                controlExcel.insertExcel(folderName, TDName, TDtotals);
            if (controlExcel.insertExcel127(folderName, deltaduName))
                controlExcel.insertExcel(folderName, deltaduName, deltafus);
            if (controlExcel.insertExcel472(folderName, deltadfName))
                controlExcel.insertExcel(folderName, deltadfName, deltaffs);
            if (controlExcel.insertExcel127(folderName, deltaName))
                controlExcel.insertExcel(folderName, deltaName, deltatotals);
            if (index != 0 && endIndex != 0)
            {
                if (controlExcel.insertExcel127(folderName, TDuName1))
                    controlExcel.insertExcel(folderName, TDuName1, TDus, index, endIndex);
                if (controlExcel.insertExcel472(folderName, TDfName1))
                    controlExcel.insertExcel(folderName, TDfName1, TDfs, index, endIndex);
                if (controlExcel.insertExcel127(folderName, TDName1))
                    controlExcel.insertExcel(folderName, TDName1, TDtotals, index, endIndex);
                if (controlExcel.insertExcel127(folderName, deltaduName1))
                    controlExcel.insertExcel(folderName, deltaduName1, deltafus, index, endIndex);
                if (controlExcel.insertExcel127(folderName, deltadfName1))
                    controlExcel.insertExcel(folderName, deltadfName1, deltaffs, index, endIndex);
                if (controlExcel.insertExcel127(folderName, deltaName1))
                    controlExcel.insertExcel(folderName, deltaName1, deltatotals, index, endIndex);
            }
            if (controlExcel.insertExcel127(folderName, Excelname))
                controlExcel.insertExcel(folderName, Excelname, TDtotals, deltatotals);


        }

        #region

        public void calcumn(List<numTest> numTests, string folderName, string sateName, int start, int end, double x, double y, double z)
        {
            List<TD> locTDus = new List<TD>();
            //Sat2BS
            List<TD> locTDfs = new List<TD>();
            //Total
            List<TD> locTDtotals = new List<TD>();

            List<TD> locdeltafus = new List<TD>();
            //Sat2BS
            List<TD> locdeltaffs = new List<TD>();
            //Total
            List<TD> locdeltatotals = new List<TD>();

            List<location> locations = new List<location>();
            ControlExcel controlExcel = new ControlExcel();
            int startNum = 0;
            for (int i = start; i <= end; i++)
            {
                numTest test = numTests[i];
                TD tDu = new TD();
                tDu.Time = test.Time;
                TD tDf = new TD();
                tDf.Time = test.Time;
                TD TDtotal = new TD();
                TDtotal.Time = test.Time;
                TD deltaFu = new TD();
                deltaFu.Time = test.Time;
                TD deltaFf = new TD();
                deltaFf.Time = test.Time;
                TD deltatotal = new TD();
                deltatotal.Time = test.Time;

                double x_sat = test.x;
                double y_sat = test.y;
                double z_sat = test.z;

                double vx_sat = test.vx;
                double vy_sat = test.vy;
                double vz_sat = test.vz;
                double latitude = 0;
                double longitude = 0;
                double x_st = calculateValue.x_st1 + x * startNum;// 6371 * Math.Cos(123.504394710077) * Math.Cos(31.788813244661);
                double y_st = calculateValue.y_st1 + y * startNum;// 6371 * Math.Cos(123.504394710077) * Math.Sin(31.788813244661);
                double z_st = calculateValue.z_st1+ z * startNum;
                location location = new location();
                location.x_st = x_st;
                location.y_st = y_st;
                location.z_st = z_st;
                location.x_bs = x_bs;
                location.y_bs = y_bs;
                location.z_bs = z_bs;
                locations.Add(location);
                double[] ep = { (x_sat - x_st), (y_sat - y_st), (z_sat - z_st) };
                double normep = CalculateEuclideanNorm(ep);
                double[] ep1 = { (x_sat - x_bs), (y_sat - y_bs), (z_sat - z_bs) };
                double normep1 = CalculateEuclideanNorm(ep1);
                for (int j = 0; j < ep.Length; j++) { ep[j] = ep[j] / normep; }
                for (int j = 0; j < ep1.Length; j++) { ep1[j] = ep1[j] / normep1; }

                //多普勒频偏计算
                double vdu = (vx_sat * ep[0]) + (vy_sat * ep[1]) + (vz_sat * ep[2]);
                double deltafu = vdu / C * fu * (-1);
                double vdf = (vx_sat * ep1[0]) + (vy_sat * ep1[1]) + (vz_sat * ep1[2]);
                double deltaff = vdf / C * ff * (-1);

                //延时计算
                double Lu = Math.Sqrt((x_sat - x_st) * (x_sat - x_st) + (y_sat - y_st) * (y_sat - y_st) + (z_sat - z_st) * (z_sat - z_st));
                double TDu = Lu / C;
                double Lf = Math.Sqrt((x_sat - x_bs) * (x_sat - x_bs) + (y_sat - y_bs) * (y_sat - y_bs) + (z_sat - z_bs) * (z_sat - z_bs));
                double TDf = Lf / C;

                tDu.number = TDu;
                tDf.number = TDf;
                TDtotal.number = TDf + TDu;
                deltaFu.number = deltafu;
                deltaFf.number = deltaff;
                deltatotal.number = deltafu + deltaff;
                locTDus.Add(tDu);
                locTDfs.Add(tDf);
                locTDtotals.Add(TDtotal);
                locdeltafus.Add(deltaFu);
                locdeltaffs.Add(deltaFf);
                locdeltatotals.Add(deltatotal);
                startNum++;
            }
            ControlTxT controlTxT = new ControlTxT();
            string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "_move_gm";
            string uName1 = "u_" + sateName + "_move_" + "gm";
            string fName1 = "f_" + sateName + "_move_" + "gm";
            string totalName1 = "total_" + sateName + "_move_" + "gm";
            if (controlExcel.insertExcel127(folderName, uName1))
                controlExcel.insertExcel(folderName, uName1, locTDus, locdeltafus);
            if (controlExcel.insertExcel472(folderName, fName1))
                controlExcel.insertExcel(folderName, fName1, locTDfs, locdeltaffs);
            if (controlExcel.insertExcel472(folderName, totalName1))
                controlExcel.insertExcel(folderName, totalName1, locTDtotals, locdeltatotals);

            controlTxT.insertASO127(folderName, uName1, locTDus, locdeltafus);
            controlTxT.insertASO472(folderName, fName1, locTDfs, locdeltaffs);
            controlTxT.insertASO(folderName, totalName1, locTDtotals, locdeltatotals);
            controlTxT.insertUni(folderName, sateName, locations, x, y, z);

            controlExcel.insertExcel(folderName, fileName, locTDus, locTDfs, locations);
        }

        public List<List<TD>> calcumnLoad(List<numTest> numTests, double fu, double ff)
        {
            List<List<TD>> tdLists = new List<List<TD>>();
            //Total
            List<TD> locTDtotals = new List<TD>();
            //Total
            List<TD> locdeltatotals = new List<TD>();

            List<location> locations = new List<location>();
            ControlExcel controlExcel = new ControlExcel();
            foreach (var item in numTests)
            {
                TD TDtotal = new TD();
                TDtotal.Time = item.Time;
                TD deltatotal = new TD();
                deltatotal.Time = item.Time;

                double x_sat = item.x;
                double y_sat = item.y;
                double z_sat = item.z;

                double vx_sat = item.vx;
                double vy_sat = item.vy;
                double vz_sat = item.vz;

                double[] ep = { (x_sat - x_st), (y_sat - y_st), (z_sat - z_st) };
                double normep = CalculateEuclideanNorm(ep);
                double[] ep1 = { (x_sat - x_bs), (y_sat - y_bs), (z_sat - z_bs) };
                double normep1 = CalculateEuclideanNorm(ep1);
                for (int j = 0; j < ep.Length; j++) { ep[j] = ep[j] / normep; }
                for (int j = 0; j < ep1.Length; j++) { ep1[j] = ep1[j] / normep1; }

                //多普勒频偏计算
                double vdu = (vx_sat * ep[0]) + (vy_sat * ep[1]) + (vz_sat * ep[2]);
                double deltafu = vdu / C * fu * (-1) * Math.Pow(10, 9);
                double vdf = (vx_sat * ep1[0]) + (vy_sat * ep1[1]) + (vz_sat * ep1[2]);
                double deltaff = vdf / C * ff * (-1) * Math.Pow(10, 9);

                //延时计算
                double Lu = Math.Sqrt((x_sat - x_st) * (x_sat - x_st) + (y_sat - y_st) * (y_sat - y_st) + (z_sat - z_st) * (z_sat - z_st));
                double TDu = Lu / C;
                double Lf = Math.Sqrt((x_sat - x_bs) * (x_sat - x_bs) + (y_sat - y_bs) * (y_sat - y_bs) + (z_sat - z_bs) * (z_sat - z_bs));
                double TDf = Lf / C;


                TDtotal.number = TDu + TDf;
                deltatotal.number = deltafu + deltaff;
                locTDtotals.Add(TDtotal);
                locdeltatotals.Add(deltatotal);
 
            }
            tdLists.Add(locTDtotals);
            tdLists.Add(locdeltatotals);
            return tdLists;
        }

        public List<TD> calcumn(List<numTest> numTests, double fu, double ff)
        {

            List<TD> locdeltafus = new List<TD>();
            //Sat2BS
            List<TD> locdeltaffs = new List<TD>();
            //Total
            List<TD> locdeltatotals = new List<TD>();

            ControlExcel controlExcel = new ControlExcel();
            int startNum = 0;
            for (int i = 0; i < numTests.Count; i++)
            {
                numTest test = numTests[i];
                TD deltaFu = new TD();
                deltaFu.Time = test.Time;
                TD deltaFf = new TD();
                deltaFf.Time = test.Time;
                TD deltatotal = new TD();
                deltatotal.Time = test.Time;

                double x_sat = test.x;
                double y_sat = test.y;
                double z_sat = test.z;

                double vx_sat = test.vx;
                double vy_sat = test.vy;
                double vz_sat = test.vz;
                double latitude = 0;
                double longitude = 0;
                //终端
                //double x_st = -2756713.92312829;// 6371 * Math.Cos(123.504394710077) * Math.Cos(31.788813244661) * Math.Pow(10,3);
                //double y_st = 4846389.73817725;// 6371 * Math.Cos(123.504394710077) * Math.Sin(31.788813244661) * Math.Pow(10,3);
                //double z_st = 3086979.55837501;
                ////基站
                //double x_bs = -2940375.29831781;// 6371 * Math.Cos(122.885488594512) * Math.Cos(32.205547319648) * Math.Pow(10,3);
                //double y_bs = 4577649.51662709;// 6371 * Math.Cos(122.885488594512) * Math.Sin(32.205547319648) * Math.Pow(10,3);
                //double z_bs = 3317495.47186574;

                double[] ep = { (x_sat - x_st), (y_sat - y_st), (z_sat - z_st) };
                double normep = CalculateEuclideanNorm(ep);
                double[] ep1 = { (x_sat - x_bs), (y_sat - y_bs), (z_sat - z_bs) };
                double normep1 = CalculateEuclideanNorm(ep1);
                for (int j = 0; j < ep.Length; j++) { ep[j] = ep[j] / normep; }
                for (int j = 0; j < ep1.Length; j++) { ep1[j] = ep1[j] / normep1; }

                //多普勒频偏计算
                double vdu = (vx_sat * ep[0]) + (vy_sat * ep[1]) + (vz_sat * ep[2]);
                double deltafu = vdu / C * fu * (-1) * Math.Pow(10, 9);
                double vdf = (vx_sat * ep1[0]) + (vy_sat * ep1[1]) + (vz_sat * ep1[2]);
                double deltaff = vdf / C * ff * (-1) * Math.Pow(10, 9);



                deltaFu.number = deltafu;
                deltaFf.number = deltaff;
                deltatotal.number = deltafu + deltaff;              
                locdeltafus.Add(deltaFu);
                locdeltaffs.Add(deltaFf);
                locdeltatotals.Add(deltatotal);
                startNum++;
            }
            return locdeltatotals;
        }

        //public void calcumn(List<numTest> numTests)
        //{
        //    fu = fu * Math.Pow(10, 9);
        //    ff = ff * Math.Pow(10, 9);
        //    location location = new location();
        //    ControlExcel controlExcel = new ControlExcel();
        //    DateTime time = new DateTime(2020, 1, 1);
        //    foreach (numTest test in numTests)
        //    {
        //        double d = (test.can_sec / 604800);
        //        double WN = Math.Floor(d); //周计数                    
        //        int daysToAdd = (int)WN * 7;
        //        DateTime newDate = time.AddDays(daysToAdd);
        //        double SOW = Math.IEEERemainder(test.can_sec, 604800); //周内秒
        //        DateTime addSecondDate = newDate.AddSeconds(SOW);
        //        TD tDu = new TD();
        //        tDu.Time = addSecondDate;
        //        TD tDf = new TD();
        //        tDf.Time = addSecondDate;
        //        TD TDtotal = new TD();
        //        TDtotal.Time = addSecondDate;
        //        TD deltaFu = new TD();
        //        deltaFu.Time = addSecondDate;
        //        TD deltaFf = new TD();
        //        deltaFf.Time = addSecondDate;
        //        TD deltatotal = new TD();
        //        deltatotal.Time = addSecondDate;

        //        double x_sat = test.x;
        //        double y_sat = test.y;
        //        double z_sat = test.z;

        //        double vx_sat = test.vx;
        //        double vy_sat = test.vy;
        //        double vz_sat = test.vz;
        //        double latitude = 0;
        //        double longitude = 0;
        //        double x_st = -2995.395 * Math.Pow(10, 3);// 6371 * Math.Cos(123.504394710077) * Math.Cos(31.788813244661);
        //        double y_st = 4524.794 * Math.Pow(10, 3);// 6371 * Math.Cos(123.504394710077) * Math.Sin(31.788813244661);
        //        double z_st = 3340.549 * Math.Pow(10, 3);
        //        double x_bs = -2933.05 * Math.Pow(10, 3);// 6371 * Math.Cos(122.885488594512) * Math.Cos(32.205547319648);
        //        double y_bs = 4536.324 * Math.Pow(10, 3);// 6371 * Math.Cos(122.885488594512) * Math.Sin(32.205547319648);
        //        double z_bs = 3379.739 * Math.Pow(10, 3);
        //        location.x_st = x_st;
        //        location.y_st = y_st;
        //        location.z_st = z_st;
        //        location.x_bs = x_bs;
        //        location.y_bs = y_bs;
        //        location.z_bs = z_bs;
        //        double[] ep = { (x_sat - x_st), (y_sat - y_st), (z_sat - z_st) };
        //        double normep = CalculateEuclideanNorm(ep);
        //        double[] ep1 = { (x_sat - x_bs), (y_sat - y_bs), (z_sat - z_bs) };
        //        double normep1 = CalculateEuclideanNorm(ep1);
        //        for (int j = 0; j < ep.Length; j++) { ep[j] = ep[j] / normep; }
        //        for (int j = 0; j < ep1.Length; j++) { ep1[j] = ep1[j] / normep1; }

        //        //多普勒频偏计算
        //        double vdu = (vx_sat * ep[0]) + (vy_sat * ep[1]) + (vz_sat * ep[2]);
        //        double deltafu = vdu / C * fu;
        //        double vdf = (vx_sat * ep1[0]) + (vy_sat * ep1[1]) + (vz_sat * ep1[2]);
        //        double deltaff = vdf / C * ff;

        //        //延时计算
        //        double Lu = Math.Sqrt((x_sat - x_st) * (x_sat - x_st) + (y_sat - y_st) * (y_sat - y_st) + (z_sat - z_st) * (z_sat - z_st));
        //        double TDu = Lu / C;
        //        double Lf = Math.Sqrt((x_sat - x_bs) * (x_sat - x_bs) + (y_sat - y_bs) * (y_sat - y_bs) + (z_sat - z_bs) * (z_sat - z_bs));
        //        double TDf = Lf / C;

        //        tDu.number = TDu;
        //        tDf.number = TDf;
        //        TDtotal.number = TDf + TDu;
        //        deltaFu.number = deltafu;
        //        deltaFf.number = deltaff;
        //        deltatotal.number = deltafu + deltaff;
        //        TDus.Add(tDu);
        //        TDfs.Add(tDf);
        //        TDtotals.Add(TDtotal);
        //        deltafus.Add(deltaFu);
        //        deltaffs.Add(deltaFf);
        //        deltatotals.Add(deltatotal);
        //    }
        //    string folderName = controlExcel.CreateFold(DateTime.Now.ToString("yyyy-MM-dd_HH-mm-ss"));
        //    string fileName = DateTime.Now.ToString("yyyyMMddHHmmss") + "gm";
        //    controlExcel.insertExcel(folderName, fileName, TDus, TDfs, numTests, location);
        //    MessageBox.Show(folderName);
        //}
        #endregion

        public SateliteData PotoSig(numTest numTest)
        {
            SateliteData sateliteData = new SateliteData();
            double GE = 398600.4418e9;
            double Ae = 6378.140e3;
            double X = numTest.x / Ae;
            double Y = numTest.y / Ae;
            double Z = numTest.z / Ae;
            double XD = numTest.vx / Math.Sqrt(GE /Ae);
            double YD = numTest.vy / Math.Sqrt(GE /Ae);
            double ZD = numTest.vz / Math.Sqrt(GE /Ae);
            double R = Math.Sqrt(X * X + Y * Y + Z * Z);

            return sateliteData;
        }

        public void calculateAddDelay(List<TD> tDfs , List<numTest> numTests)
        {
            for (int i = 0; i < numTests.Count; i++)
            {
                TD tD = tDfs[i];
                numTest num = numTests[i];
                double alfa = tD.number * w;
                Matrix<double> delta3X3 = Matrix<double>.Build.DenseOfArray(new double[,]
                {{Math.Cos(alfa), Math.Sin(alfa) , 0}, {-Math.Sin(alfa), Math.Cos(alfa), 0},{0, 0, 1}});
                Vector<double> vector1x3 = Vector<double>.Build.DenseOfArray(new double[] { num.x, num.y, num.z });
                Vector<double> result = delta3X3 * vector1x3;
            }
        }
        public double CalculateEuclideanNorm(double[] vector)
        {
            double sumOfSquares = 0;

            foreach (double element in vector)
            {
                sumOfSquares += element * element;
            }

            return Math.Sqrt(sumOfSquares);
        }

        /// <summary>
        /// 经纬度转ECEF坐标
        /// </summary>
        /// <param name="latitude">纬度</param>
        /// <param name="longitude">经度</param>
        /// <param name="altitude">高度</param>
        public Titude ConvertGeodeticToECEF(Titude titude)
        {
            double lambda = titude.longitude * Math.PI / 180;
            double phi = titude.latitude * Math.PI / 180;
            double h = titude.altitude;

            double eSq = 2 * EarthFlattening - EarthFlattening * EarthFlattening;
            double N = EarthSemiMajorAxis / Math.Sqrt(1 - eSq * Math.Sin(phi) * Math.Sin(phi));

            double x = (N + h) * Math.Cos(phi) * Math.Cos(lambda);
            double y = (N + h) * Math.Cos(phi) * Math.Sin(lambda);
            double z = (N * (1 - eSq) + h) * Math.Sin(phi);

            titude.X = x;
            titude.Y = y;
            titude.Z = z;

            return titude;
        }

        /// <summary>
        /// 经纬度转换度分秒
        /// </summary>
        /// <param name="decimalDegrees"></param>
        /// <returns></returns>
        public string DecimalToDMS(double decimalDegrees)
        {
            // 计算度
            int degrees = (int)decimalDegrees;

            // 计算分钟
            double decimalMinutes = (decimalDegrees - degrees) * 60;
            int minutes = (int)decimalMinutes;

            // 计算秒
            double seconds = (decimalMinutes - minutes) * 60;

            // 返回格式化的字符串
            return string.Format("{0}° {1}' {2:0.##}\"", degrees, minutes, seconds);
        }

        /// <summary>
        /// ECEF坐标转换经纬度
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="z"></param>
        /// <returns></returns>
        public Titude ECEFToLatLon(Titude titude)
        {
            //// 定义一些常用的计算中间变量
            //double lon, lat, alt, p, theta, sin_theta, cos_theta;
            //double e_squared = 1 - (EarthSemiMinorAxis * EarthSemiMinorAxis) / (EarthSemiMajorAxis * EarthSemiMajorAxis);

            //p = Math.Sqrt(titude.X * titude.X + titude.Y * titude.Y);
            //theta = Math.Atan2(titude.Z * EarthSemiMajorAxis, p * EarthSemiMinorAxis);
            //sin_theta = Math.Sin(theta);
            //cos_theta = Math.Cos(theta);

            //lon = Math.Atan2(titude.Y, titude.X);
            //lat = Math.Atan2(titude.Z + e_squared * EarthSemiMinorAxis * sin_theta * sin_theta * sin_theta,
            //                p - e_squared * EarthSemiMajorAxis * cos_theta * cos_theta * cos_theta);
            //alt = p / Math.Cos(lat) - EarthSemiMajorAxis / Math.Sqrt(1 - e_squared * Math.Sin(lat) * Math.Sin(lat));

            //// 将弧度转换为度数
            //lon = lon * 180 / Math.PI;
            //lat = lat * 180 / Math.PI;

            //titude.latitude = lat;
            //titude.longitude = lon;
            //titude.altitude = alt;

            double a = 6378137.0;
            double b = 6356752.3142;
            double e = Math.Sqrt(a * a - b * b) / b;

            double p = Math.Sqrt(titude.X * titude.X + titude.Y * titude.Y);
            double theta = Math.Atan2(titude.Z * a, p * b);

            titude.latitude = Math.Atan2(titude.Z + e * e * b * Math.Pow(Math.Sin(theta), 3), p - e * e * a * Math.Pow(Math.Cos(theta), 3));
            titude.longitude = Math.Atan2(titude.Y, titude.X);
            titude.altitude = p / Math.Cos(titude.latitude) - a / Math.Sqrt(1 - e * e * Math.Sin(titude.latitude) * Math.Sin(titude.latitude));

            // 将弧度转换为度
            titude.latitude *= 180.0 / Math.PI;
            titude.longitude *= 180.0 / Math.PI;

            return titude;
        }
        /// <summary>
        /// 余弦定理
        /// </summary>
        /// <param name="a"></param>
        /// <param name="b"></param>
        /// <param name="c"></param>
        /// <returns></returns>
        public (double α, double β, double γ) lineToCorner(double a, double b, double c)
        {
            double α, β, γ;
            // 计算夹角的余弦值
            double cosA = (c * c + b * b - a * a) / (2 * b * c);
            double cosB = (a * a + c * c - b * b) / (2 * a * c);
            double cosC = (a * a + b * b - c * c) / (2 * a * b);
            // 计算夹角的弧度值
            double angleA = Math.Acos(cosA);
            double angleB = Math.Acos(cosB);
            double angleC = Math.Acos(cosC);
            // 将弧度转换为角度
            double angleAinDegress = angleA * (180 / Math.PI);
            double angleBinDegrees = angleB * (180 / Math.PI);
            double angleCinDegrees = angleC * (180 / Math.PI);

            return (α: angleAinDegress, β: angleBinDegrees, γ: angleCinDegrees);
        }

        public DateTime TimeSpanToUTC(int TimeSpan)
        {
            DateTime time = new DateTime(2020, 1, 1);
            DateTime newDate = time.AddSeconds(TimeSpan);
            return newDate;
        }

        public Double UTCToTimeSpan(DateTime dateTime)
        {
            DateTime UTCTime = new DateTime(1970, 1, 1);
            TimeSpan timeSpan = dateTime - UTCTime;
            return timeSpan.TotalSeconds;
        }
    }
}
